﻿; (function ($, win, document, undefined) {

    var version = '1.0.1';
    var pluginName = 'flextabledit';
    var texts = {
        cut: "Cut",
        copy: "Copy",
        paste: "Paste",
        insert: "Insert",
        erase: "Erase",
        remove: "Remove",
        columnName: "Column name"
    };

    function Plugin(element, options) {
        // Get the main element
        this.$element = $(element);
        // Initialize plugin
        this._init(options);
        // Create and show table
        this._renderTable();
    };

    Plugin.prototype = {

        // Select column
        _getAbsPosition: function ($parentEl, width, height) {
            var viewPortWidth = $(window).width();
            var offsetParent = $parentEl.offset();
            var offsetTable = this.$element.offset();
            var tableWidth = this.$table.outerWidth();
            var leftPos = offsetParent.left - offsetTable.left - 1;
            if (leftPos + width > tableWidth) {
                leftPos = tableWidth - width;
                if (leftPos < 0) {
                    leftPos = 0;
                }
            }
            var topPos = offsetParent.top - offsetTable.top + 26;
            var pos = { left: leftPos, right: 0, top: topPos };
            return pos;
        },

        // Unselect column, row, cell
        _unselect: function () {
            // Unselect a previously selected cell, column, row, popup menu
            this.$element.find('th').removeClass('flxtblColSelected');
            var $rows = this.$element.find('tbody tr');
            for (var r = 0; r < $rows.length; r++) {
                $($rows[r]).find('td').removeClass('flxtblColSelected flxtblRowSelected cellSelected');
            }
            if (this.$menuPopup) {
                this.$menuPopup.remove();
                this.$menuPopup = null;
            }
        },

        // Clear the clipboard
        _clearClipBoard: function () {
            // Unselect a marked cell, column, row
            this.$element.find('th').removeClass('flxtblColMarked');
            var $rows = this.$element.find('tbody tr');
            for (var r = 0; r < $rows.length; r++) {
                $($rows[r]).find('td').removeClass('flxtblColMarked flxtblRowMarked cellMarked');
            }
            // Clear clipboard
            this.clipBoard = null;
        },

        // Remove menu popup button
        _removeMenuPopupBtn: function () {
            if (this.$menuPopupBtn) {
                // Remove popup menu button
                this.$menuPopupBtn.remove();
                this.$menuPopupBtn = null;
            }
        },

        // Unselect all
        _unselectAll: function () {
            // Unselect a previously selected cell, column, row, popup menu, and popup menu button
            this._unselect();
            if (this.$menuPopupBtn) {
                // Remove cell popup menu button
                this.$menuPopupBtn.remove();
                this.$menuPopupBtn = null;
            }
        },

        // Select column
        _selectCol: function (colIndex, mark) {
            // Unselect a previously selected cell, column, row, popup menu
            this._unselect();
            // Select the given column
            var $headers = this.$element.find('th');
            var $rows = this.$element.find('tbody tr');
            var $th = $($headers[colIndex]);
            $th.addClass('flxtblColSelected');
            if (mark) {
                $th.addClass('flxtblColMarked');
            }
            for (var r = 0; r < $rows.length; r++) {
                var $cells = $($rows[r]).find('td');
                var $td = $($cells[colIndex]);
                $td.addClass('flxtblColSelected');
                if (mark) {
                    $td.addClass('flxtblColMarked');
                }
            }
        },

        // Select row
        _selectRow: function (rowIndex, mark) {
            // Unselect a previously selected cell, column, row, popup menu
            this._unselect();
            // Select the given row
            var $rows = this.$element.find('tbody tr');
            var $tds = $($rows[rowIndex - 1]).find('td');
            $tds.addClass('flxtblRowSelected');
            if (mark) {
                $tds.addClass('flxtblRowMarked');
            }
        },

        // Select cell
        _selectCell: function (rowIndex, colIndex, mark) {
            // Unselect a previously selected cell, column, row, popup menu
            this._unselect();
            // Select the given cell
            var $rows = this.$element.find('tbody tr');
            var $td = $($rows[rowIndex - 1]).find('td').eq(colIndex);
            $td.addClass('cellSelected');
            if (mark) {
                $td.addClass('cellMarked');
            }
        },

        // Handle select
        _onCellClicked: function (el, row, col, mark) {
            // Render menu popup button and select the cell, the column or the row (whatever is appropriate).
            var leftPos = -2;
            var topPos = 25;
            this.$btnParent = $(el).parent();
            // Select column, row, or cell
            if (row == 0) {
                this._selectCol(col, mark);
                var $lastRow = this.$element.find('tbody tr:last');
                this.$btnParent = $lastRow.find('td').eq(col);
            }
            else if (col == 0) {
                this._selectRow(row, mark);
                this.$btnParent = $(el).parent().find('td:first');
            }
            else {
                this._selectCell(row, col, mark);
            }
            // Render a small popup menu button
            if (this.$menuPopupBtn) {
                this.$menuPopupBtn.remove();
            }
        },

        // Handle event occurring on <input> elements
        _onInputEvent: function (el, ev) {
            ev.stopPropagation();
            switch (ev.type) {
                case 'click':
                    var rowIndex = ($(el).parent().is('th')) ? 0 : $(el).parent().parent().index() + 1;
                    var colIndex = $(el).parent().index();
                    this._onCellClicked(el, rowIndex, colIndex);
                    break;
                case 'input':
                    this._unselect();
                    var rowIndex = ($(el).parent().is('th')) ? 0 : $(el).parent().parent().index() + 1;
                    var colIndex = $(el).parent().index() + 1;
                    if (rowIndex == 1) {
                        colIndex = colIndex - 1;
                    }
                    this._calculate(el, rowIndex, colIndex);
                    break;
            }
        },

        _calculate: function (el, row, col) {
            var $rows = this.$element.find('tbody tr');
            var max = 'N';
            var rrow = row - 1;
            var colY = 2;
            var $td0 = $($rows[rrow]).find('td').eq(3);
            if ($($rows[rrow]).find("td").length == 15) {
                colY = 1;
                $td0 = $($rows[rrow]).find('td').eq(2);
            }
            $($rows[rrow]).find("td").each(function (index, element) {
                if (index > colY) {
                    $this = $(this).text();
                    if ($this != 'Y' && $this != 'N') {
                        $this = $(this).find("select").val();
                    }
                    if ($this == 'Y') $td0.html($this);;
                }
            });
            
        },

        _getDaysOfMonth: function () {
            // Return today's date and time
            var currentTime = new Date();

            // returns the month (from 0 to 11)
            var month = currentTime.getMonth();

            // returns the year (four digits)
            var year = currentTime.getFullYear();

            var monthStart = new Date(year, month, 1);
            var monthEnd = new Date(year, month + 1, 1);
            var monthLength = (monthEnd - monthStart) / (1000 * 60 * 60 * 24)
            return monthLength;
        },

        // Handle event occurring on the first cell of a row
        _onRowEvent: function (el, ev) {
            ev.stopPropagation();
            var rowIndex = $(el).parent().index() + 1;
            this._onCellClicked(el, rowIndex, 0);
        },

        // Create table from content array and show it
        _renderTable: function () {
            var self = this;
            var content = this.settings.content;
            if (content && content.length != 0) {
                this.nrofDataCols = content[0].length;
                this.nrofDataRows = content.length - 1;
                var d = new Date();
                var month = d.getMonth();
                var html = '<table id="pm-ap-edit-product-holding-table" class="flexTable ';
                html += this.settings.addTableClass;
                html += '">';
                if (this.settings.headerIncluded) {
                    html += '<thead><tr><th></th>';
                    for (var c = 0; c < this.nrofDataCols; c++) {
                        switch (c) {
                            case 0:
                                html += '<th width="30%">';
                                html += content[0][c];
                                html += '</th>';
                                break;
                            case month + 3:
                                html += '<th class="column-title" id="edit-table-from">';
                                html += content[0][c];
                                html += '</th>';
                                break;
                            default:
                                html += '<th>';
                                html += content[0][c];
                                html += '</th>';
                                break;
                        }

                    }
                    html += '</tr></thead>';
                }
                html += '<tbody>';
                for (var r = 1; r < content.length; r++) {
                    if (content[r][0] != 'child') {
                        html += '<tr><td rowspan="' + content[r][17] + '" width="8%" class="pm-ap-table-row-col-first">';
                        html += content[r][0];
                        html += '</td>';
                    }
                    for (var c = 1; c < this.nrofDataCols + 1; c++) {
                        if (c < month + 4) {
                            html += '<td>';
                            html += (content[r][c] + "").replace(/\"/g, '&quot;');
                            html += '</td>';
                        } else {
                            if ((content[r][c] + "").replace(/\"/g, '&quot;') == 'N') {
                                html += '<td><select id="mygroup' + r + c + '"><option value="Y">Yes</option><option value="N" selected="selected">No</option></select></td>';
                            } else {
                                html += '<td><select id="mygroup' + r + c + '"><option value="Y" selected="selected">Yes</option><option value="N">No</option></select></td>';
                            }
                        }
                    }
                    html += '</tr>';
                }
                html += '</tbody></table>';
                this.$element.addClass('flexTableContainer');
                // Create table and append it to the container
                this.$table = $(html);
                this.$element.append(this.$table);

                // Bind event handlers
                this.$element.find('select').on('click.table input.table', function (ev) {
                    self._onInputEvent(this, ev);
                });
                this.$element.find('tbody td:first-child').on('click.table', function (ev) {
                    self._onRowEvent(this, ev);
                });
            }
            $('body').on('click.table keyup.table', function (ev) {
                if (ev.type == 'click') {
                    self._unselect();
                    self._removeMenuPopupBtn();
                }
                else if (ev.type == 'keyup') {
                    if (ev.keyCode === 27) {
                        self._clearClipBoard();
                        self._unselect();
                    }
                }
            });
            this.state = 'presented';
        },

        // Initialize
        _init: function (options) {
            var self = this;
            var defaults =
            {
                headerIncluded: true,
                addTableClass: "",
                texts: texts,
                onOpen: function () { },
                onClose: function () { }
            };
            this.settings = $.extend(defaults, options || {});
            this.nrofDataCols = 0;
            this.nrofDataRows = 0;
            this.clipBoard = null;
            this.state = 'initialized';
        },

        // Get the table cell data
        // Arguments: none
        getData: function (argsArray) {
            // Iterate table and push the input element values into a 'data' array
            // The array has the same format as the 'content' array passed in the plugin constructor.
            var dataArray = [];
            var $headRow = this.$element.find('thead tr');
            if ($headRow.length == 1) {
                var $inputs = $headRow.find('td');
                var rowData = [];
                var $bodyRows = this.$element.find('tbody tr');
                for (var r = 0; r < $bodyRows.length; r++) {
                    $inputs = $($bodyRows[r]).find('td');
                    rowData = [];
                    for (var c = 0; c < $inputs.length; c++) {
                        var val = $($inputs[c]).text();
                        if ($($inputs[c]).find("select").length) {
                            val = $($inputs[c]).find("select").val();
                        }
                        rowData.push(val);
                    }

                    dataArray.push(JSON.stringify(rowData));
                }
            }
            return dataArray;
        },

        // Close the table
        // Arguments: none
        close: function (argsArray) {
            this._unselectAll();
            this.$table.remove();
            $('body').off();
            this.state = 'closed';
        },

        // Destroy the plugin
        // Arguments: none
        destroy: function (argsArray) {
            this.close();
            $.removeData(this.$element[0], pluginName);
        },

    };

    $.fn[pluginName] = function (methodOrOptions) {
        var instance = $(this).data(pluginName);
        if (instance &&
            methodOrOptions &&
            typeof methodOrOptions != 'object' &&
            methodOrOptions.indexOf('_') != 0) {
            // Call method and return possible result value of the method
            return instance[methodOrOptions](Array.prototype.slice.call(arguments, 1));
        }
        if (typeof methodOrOptions === 'object' || !methodOrOptions) {
            instance = new Plugin(this, methodOrOptions);
            $(this).data(pluginName, instance);
            return this;
        }
        $.error('Wrong call to ' + pluginName);
        return this;
    };

})(jQuery);

